

#ifndef SYNTAX_PARSER_H 

#define SYNTAX_PARSER_H

#include "syntax_tree.h"
#include "lexic_units.h"

class Parser
{
public:
	Parser();
	~Parser();

	void StartParsing();


private:
	int CurrentLexicPosition;

    // helper methods
	bool getNextLexicUnit2(int *position, LexicUnit * unit);
    bool getNextLexicUnit(int *position, LexicUnit * unit);
    bool isClassProduction(int currentPosition);
    bool isMethodProduction(int currentPosition);
    bool isFieldProduction(int currentPosition);
    bool isPropertyProduction(int currentPosition);
    
    //posebne za varaible_value

    void Parse_Name_Ambiguous(SyntaxTreeNode * parent);
    void Parse_NameAdd_Ambiguous(SyntaxTreeNode * parent);
   
    
	// Napravljeno
	void Parse_ProgramBody(SyntaxTreeNode * parent);
	
	// Zadatak 1
	void Parse_GppFile(SyntaxTreeNode * parent);
	void Parse_UsingDirectives(SyntaxTreeNode * parent);
	void Parse_UsingDirective(SyntaxTreeNode * parent);
	void Parse_FileBody(SyntaxTreeNode * parent);

	// Zadatak 2
	void Parse_MainDefinition(SyntaxTreeNode * parent);
	
	// Zadatak 18
	void Parse_Name(SyntaxTreeNode * parent);
	void Parse_NameAdd(SyntaxTreeNode * parent);
	void Parse_NamePeriodAdd(SyntaxTreeNode * parent);
	void Parse_ArrayDefinitionsSize(SyntaxTreeNode * parent);
	void Parse_ArrayDefinitionSize(SyntaxTreeNode * parent);

	// Zadatak 3
	void Parse_DataType(SyntaxTreeNode * parent);
	void Parse_EnumDefinition(SyntaxTreeNode * parent);
	void Parse_EnumNames(SyntaxTreeNode * parent);
	void Parse_EnumNamesAdd(SyntaxTreeNode * parent);
	void Parse_TemplateDefinition(SyntaxTreeNode * parent);
	void Parse_TemplateUse(SyntaxTreeNode * parent);
	void Parse_TemplatesList(SyntaxTreeNode * parent);
	void Parse_TemplatesListAdd(SyntaxTreeNode * parent);
	void Parse_ClassInheritName(SyntaxTreeNode * parent);
	void Parse_NameCommaAdd(SyntaxTreeNode * parent);

	// Napravljeno
	void Parse_ClassMods(SyntaxTreeNode * parent);

	// Zadatak 4
	void Parse_ClassDefinition(SyntaxTreeNode * parent);
	void Parse_ClassMod(SyntaxTreeNode * parent);
	void Parse_ClassInherit(SyntaxTreeNode * parent);
	void Parse_ConstructorDefinition(SyntaxTreeNode * parent);
	void Parse_ConstrMod(SyntaxTreeNode * parent);
	void Parse_ConstrInherit(SyntaxTreeNode * parent);
	void Parse_ConstrBody(SyntaxTreeNode * parent);

	// Zadatak 5
	void Parse_ClassBody(SyntaxTreeNode * parent);
	void Parse_ClassBodyAdd(SyntaxTreeNode * parent);


	// Zadatak 6
	void Parse_FieldDefinition(SyntaxTreeNode * parent);
	void Parse_FieldMods(SyntaxTreeNode * parent);
	void Parse_FieldMod(SyntaxTreeNode * parent);
	void Parse_FieldNames(SyntaxTreeNode * parent);
	void Parse_FieldName(SyntaxTreeNode * parent);
	void Parse_FieldNamesAdd(SyntaxTreeNode * parent);
	void Parse_Equals(SyntaxTreeNode * parent);
	void Parse_ArrayDefinitions(SyntaxTreeNode * parent);
	void Parse_ArrayDefinition(SyntaxTreeNode * parent);

	// Zadatak 7
	void Parse_PropertyDefinition(SyntaxTreeNode * parent);
	void Parse_PropertyMods(SyntaxTreeNode * parent);
	void Parse_PropertyMod(SyntaxTreeNode * parent);
	void Parse_PropertyName(SyntaxTreeNode * parent);
	void Parse_PropArrayDefs(SyntaxTreeNode * parent);
	void Parse_PropArrayDef(SyntaxTreeNode * parent);
	void Parse_PropertyBody(SyntaxTreeNode * parent);
	void Parse_PropertyRead(SyntaxTreeNode * parent);
	void Parse_PropertyWrite(SyntaxTreeNode * parent);
	void Parse_MethodDefinition(SyntaxTreeNode * parent);
	void Parse_MethodMods(SyntaxTreeNode * parent);
	void Parse_MethodMod(SyntaxTreeNode * parent);
	void Parse_StartProcess(SyntaxTreeNode * parent);

	// Zadatak 8
	void Parse_MethodBodyDecl(SyntaxTreeNode * parent);
	void Parse_MethodBody(SyntaxTreeNode * parent);
	void Parse_LabelMethodStatement(SyntaxTreeNode * parent);
	void Parse_MethodLabels(SyntaxTreeNode * parent);
	//void Parse_MethodStatements(SyntaxTreeNode * parent);
	void Parse_NamespaceDefinition(SyntaxTreeNode * parent);
	void Parse_Parameters(SyntaxTreeNode * parent);
	void Parse_ParameterCommaAdd(SyntaxTreeNode * parent);
	void Parse_ParametersAdd(SyntaxTreeNode * parent);
	void Parse_Parameter(SyntaxTreeNode * parent);
	void Parse_Arguments(SyntaxTreeNode * parent);
	void Parse_ArgumentCommaAdd(SyntaxTreeNode * parent);
	void Parse_ArgumentsAdd(SyntaxTreeNode * parent);





	// Zadatak 9
	void Parse_VariableDefinition(SyntaxTreeNode * parent);
	void Parse_MethodCall(SyntaxTreeNode * parent);
	void Parse_IfStatement(SyntaxTreeNode * parent);
	void Parse_BlockStatement(SyntaxTreeNode * parent);
	void Parse_ElsePart(SyntaxTreeNode * parent);
	void Parse_SwitchCaseStatement(SyntaxTreeNode * parent);
	void Parse_SwitchCaseCases(SyntaxTreeNode * parent);
	void Parse_SwitchCaseCase(SyntaxTreeNode * parent);
	//void Parse_SwitchCaseBlock(SyntaxTreeNode * parent);	
	void Parse_SwitchCaseDefault(SyntaxTreeNode * parent);

   // Zadatak 17
   void Parse_Label(SyntaxTreeNode * parent);
   void Parse_ReturnStatement(SyntaxTreeNode * parent);
	void Parse_StartStatement(SyntaxTreeNode * parent);
   void Parse_InfBegin(SyntaxTreeNode * parent);
   void Parse_BlockLabels(SyntaxTreeNode * parent);
   void Parse_BlockLabel(SyntaxTreeNode * parent);
   void Parse_ValuePairsAdds(SyntaxTreeNode * parent);

   // Zadatak 21
	void Parse_MethodStatement(SyntaxTreeNode * parent);
	void Parse_Assignment(SyntaxTreeNode * parent);
	void Parse_SimpleStatement(SyntaxTreeNode * parent);


	// Zadatak 22
	void Parse_DefineBodyStatements(SyntaxTreeNode * parent);
	void Parse_DefineBodyStatement(SyntaxTreeNode * parent);


	// Zadatak 10
	void Parse_WhileStatement(SyntaxTreeNode * parent);
	void Parse_DowhileStatement(SyntaxTreeNode * parent);
	void Parse_ForStatement(SyntaxTreeNode * parent);
	void Parse_BreakStatement(SyntaxTreeNode * parent);
	void Parse_ContinueStatement(SyntaxTreeNode * parent);
	void Parse_GotoStatement(SyntaxTreeNode * parent);
	void Parse_StartAssignments(SyntaxTreeNode * parent);
	void Parse_StartAssignmentAdd(SyntaxTreeNode * parent);
	void Parse_StartAssignmentCommaAdd(SyntaxTreeNode * parent);
	void Parse_StartAssignment(SyntaxTreeNode * parent);
	void Parse_StopStatement(SyntaxTreeNode * parent);
	void Parse_AssignmentDerivation(SyntaxTreeNode * parent);


	// Zadatak 11
	void Parse_NumericMod(SyntaxTreeNode * parent);
	void Parse_InfEnd(SyntaxTreeNode * parent);
	void Parse_ValuePairs(SyntaxTreeNode * parent);
	void Parse_ValuePair(SyntaxTreeNode * parent);
	void Parse_SignValue(SyntaxTreeNode * parent);
	void Parse_ModelDefinition(SyntaxTreeNode * parent);
	void Parse_ModelDefinitionIn(SyntaxTreeNode * parent);
	void Parse_ModelDefinitionOut(SyntaxTreeNode * parent);
	void Parse_LabelList(SyntaxTreeNode * parent);
	void Parse_Labels(SyntaxTreeNode * parent);
	void Parse_CommaLabel(SyntaxTreeNode * parent);
	void Parse_ModelMod(SyntaxTreeNode * parent);
	void Parse_ValuePairAdd(SyntaxTreeNode * parent);








	// Zadatak 12
	void Parse_ModelBody(SyntaxTreeNode * parent);
	void Parse_ModelDefine(SyntaxTreeNode * parent);
	void Parse_LabelGpssBlock(SyntaxTreeNode * parent);
	void Parse_ModelStructure(SyntaxTreeNode * parent);
	void Parse_GpssBlock(SyntaxTreeNode * parent);

	




	// Zadatak 13
	void Parse_GenerateBlock(SyntaxTreeNode * parent);
	void Parse_UptoExpression(SyntaxTreeNode * parent);
	void Parse_AfterExpression(SyntaxTreeNode * parent);
	void Parse_EveryExpression(SyntaxTreeNode * parent);
	void Parse_PlusMinusExpression(SyntaxTreeNode * parent);
	void Parse_TransList(SyntaxTreeNode * parent);
	void Parse_TransListAdds(SyntaxTreeNode * parent);
	void Parse_TransListAdd(SyntaxTreeNode * parent);
	void Parse_AdvanceBlock(SyntaxTreeNode * parent);
	void Parse_EnterBlock(SyntaxTreeNode * parent);
	void Parse_FormingExpression(SyntaxTreeNode * parent);
	void Parse_LeaveBlock(SyntaxTreeNode * parent);
	void Parse_SeizeBlock(SyntaxTreeNode * parent);
	void Parse_ReleaseBlock(SyntaxTreeNode * parent);
	void Parse_InqueueBlock(SyntaxTreeNode * parent);
	void Parse_OutqueueBlock(SyntaxTreeNode * parent);
	void Parse_ArriveBlock(SyntaxTreeNode * parent);
	void Parse_DepartBlock(SyntaxTreeNode * parent);
	void Parse_ModelInstanceBlock(SyntaxTreeNode * parent);
	void Parse_GotoBlock(SyntaxTreeNode * parent);


	// Zadatak 16
	// lagana nejednoznacnost
	void Parse_GenerateTransactions(SyntaxTreeNode * parent);
	void Parse_TerminateBlock(SyntaxTreeNode * parent);
	void Parse_UnitsInExpression(SyntaxTreeNode * parent);
	void Parse_UnitsFromExpression(SyntaxTreeNode * parent);
	void Parse_Timeout(SyntaxTreeNode * parent);
	void Parse_GatherBlock(SyntaxTreeNode * parent);
	void Parse_SimRun(SyntaxTreeNode * parent);



	






	// Zadatak 14

	void Parse_IfBlock(SyntaxTreeNode * parent);
	void Parse_WaitBlock(SyntaxTreeNode * parent);
	void Parse_OnSensitivityList(SyntaxTreeNode * parent);
	void Parse_WhileUntil(SyntaxTreeNode * parent);
	void Parse_ThenStructure(SyntaxTreeNode * parent);
	void Parse_ElseStructure(SyntaxTreeNode * parent);
	void Parse_SensitivityList(SyntaxTreeNode * parent);
	void Parse_SensitivityListAdds(SyntaxTreeNode * parent);
	void Parse_SensitivityListAdd(SyntaxTreeNode * parent);
	void Parse_JoinGroupBlock(SyntaxTreeNode * parent);
	void Parse_LeaveGroupBlock(SyntaxTreeNode * parent);
	void Parse_CreateBlock(SyntaxTreeNode * parent);
	void Parse_SendTo(SyntaxTreeNode * parent);
	void Parse_SplitBlock(SyntaxTreeNode * parent);
	void Parse_IntoExpression(SyntaxTreeNode * parent);

	// Zadatak 15

	void Parse_AndDestroy(SyntaxTreeNode * parent);
	void Parse_ExecuteBlock(SyntaxTreeNode * parent);
	void Parse_Simulation(SyntaxTreeNode * parent);
	void Parse_SimulationBody(SyntaxTreeNode * parent);
	void Parse_SimulationStmt(SyntaxTreeNode * parent);
	void Parse_SimConfiguration(SyntaxTreeNode * parent);
	void Parse_SimClear(SyntaxTreeNode * parent);
	void Parse_SimReset(SyntaxTreeNode * parent);
	void Parse_Initialisation(SyntaxTreeNode * parent);
	void Parse_InitialValues(SyntaxTreeNode * parent);
	void Parse_InitialValueAdd(SyntaxTreeNode * parent);
	void Parse_InitialValue(SyntaxTreeNode * parent);
	void Parse_InitialValueComma(SyntaxTreeNode * parent);


			
	//Zadatak 20

	void Parse_Expression(SyntaxTreeNode * parent);
	void Parse_ExpressionAdds(SyntaxTreeNode * parent);
	void Parse_ExpressionAdd(SyntaxTreeNode * parent);
	void Parse_Expression2(SyntaxTreeNode * parent);
	void Parse_Expression2Adds(SyntaxTreeNode * parent);
	void Parse_Expression2Add(SyntaxTreeNode * parent);
	void Parse_Expression3(SyntaxTreeNode * parent);
	void Parse_Expression3Adds(SyntaxTreeNode * parent);
	void Parse_Expression3Add(SyntaxTreeNode * parent);
	void Parse_Expression4(SyntaxTreeNode * parent);
	void Parse_Expression5(SyntaxTreeNode * parent);
	void Parse_Expression6(SyntaxTreeNode * parent);
	void Parse_Expression6Adds(SyntaxTreeNode * parent);
	void Parse_Expression6Add(SyntaxTreeNode * parent);
	void Parse_Expression7(SyntaxTreeNode * parent);
	void Parse_Expression7Adds(SyntaxTreeNode * parent);
	void Parse_Expression7Add(SyntaxTreeNode * parent);
	void Parse_Expression8(SyntaxTreeNode * parent);
	void Parse_Expression9(SyntaxTreeNode * parent);


	// zadatak 19
	void Parse_Value(SyntaxTreeNode * parent);
	void Parse_VariableValue(SyntaxTreeNode * parent);
	void Parse_VariableValueAdd(SyntaxTreeNode * parent);
	void Parse_PeriodVariableValue(SyntaxTreeNode * parent);


   void Parse_TracePart(SyntaxTreeNode * parent);

	//
};

#endif

